package com.pro.xwt.rest.controller;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mysql.jdbc.StringUtils;
import com.pro.xwt.common.model.BEmployee;
import com.pro.xwt.common.model.DFile;
import com.pro.xwt.common.service.BProjectService;
import com.pro.xwt.common.service.DFileService;
import com.pro.xwt.common.utils.Common;
import com.pro.xwt.common.utils.ThreeDESUtil;
import com.pro.xwt.rest.ResponseResult;

@Controller
@RequestMapping("/files")
public class DFileController {

	@Autowired
	DFileService dFileService;
    @Autowired
    BProjectService bProjectService;

	/**
	 * 下载文件的接口
	 */
	@RequestMapping(method = { RequestMethod.GET }, value = "/{id}")
	@ResponseBody
	public ResponseResult getUrl(@PathVariable String id, HttpServletRequest request, HttpServletResponse response){
		String key = generateToken(id);
		String path = ""+key;
		/*try {
			path = URLEncoder.encode(path, "utf-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		return ResponseResult.success("成功", path);
	}
	
	/**
	 * 
	 * 下载文件接口
	 * 
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(method = { RequestMethod.GET }, value = "/getFile")
	@ResponseBody
	public void down(String pathId, HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		//pathId = pathId.replace(" ", "+");
		//pathId = URLDecoder.decode(pathId, "UTF-8");
		Map<String, Object> map = decodeToken(pathId);
		String id = (String)map.get("userInfos");
		Long ms = Long.parseLong(map.get("ms").toString());
		Long s =  System.currentTimeMillis();
		long ss = s-ms;
		//小于30分钟时可下载
		if (ss < 30*60*1000) {
			BufferedInputStream bis = null;
			DFile dFile = dFileService.findById(id);
			int size = 1024;
			OutputStream ops = null;
	
			if (dFile == null) {
				return;
			}
			//response.setContentType("application/force-download");
			
			// 获取文件路径
			String address = Common.FILE_SAVE_BASEPATH+dFile.getStoragePath();
			String fileName = null;
			try {
				File file = new File(address);
				
				response.setContentType("application/octet-stream");  
				 boolean isMSIE = isMSBrowser(request);  
				  if (isMSIE) {  
				                fileName = URLEncoder.encode(dFile.getName(), "UTF-8");  
				            } else {  
				                fileName = new String(dFile.getName().getBytes("UTF-8"), "ISO-8859-1");  
				            }  
				            response.setHeader("Content-disposition", "attachment;filename=\"" + fileName + "\""); 
				
				//String fileName = URLEncoder.encode(dFile.getName(), "UTF-8");
				//response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
				response.setContentLength((int) file.length());  
				bis = new BufferedInputStream(new FileInputStream(file));
				ops = response.getOutputStream();
				byte[] byteArray = new byte[size];
				int temp = 0;
				while ((temp = bis.read(byteArray)) != -1) {
					ops.write(byteArray, 0, temp);
				}
			} catch (Exception e) {
				 e.printStackTrace();  
			} finally {
				if (bis != null) {
					bis.close();
					bis = null;
				}
				if (ops != null) {
					ops.close();
					ops = null;
				}
	
			}
			
		}

	}
	
	/**
	 * 文件名修改的接口
	 */
	@RequestMapping(method = { RequestMethod.PATCH }, value = "/{id}/projects/{projId}")
	@ResponseBody
	public ResponseResult updateName(@PathVariable String id,@PathVariable String projId,@RequestBody DFile dFile,HttpServletRequest request){
		DFile file = dFileService.findById(id);
		BEmployee user =(BEmployee) request.getAttribute("user");
		if (!isOwnerOrAdmin(user, projId) && !file.getUploadEmpId().equals(user.getId())) {
			return ResponseResult.fail("你没有该权限", false);
		}
		String fileSuffix=file.getName().substring(file.getName().lastIndexOf(".")+1);
		String fileName = dFile.getName()+"."+fileSuffix;
		dFile.setId(id);
		dFile.setName(fileName);
		int flag = dFileService.update(dFile);
		if(flag==1){
			DFile fi = dFileService.findById(id);
			return ResponseResult.success("文件名修改成功", fi);
		}
		return ResponseResult.success("文件名修改失败", flag);
		
	}
	/**
	 * 文件删除
	 * @param id
	 * @return
	 */
	@RequestMapping(method = { RequestMethod.DELETE }, value = "/{id}/projects/{projId}")
	@ResponseBody
	public ResponseResult deleteFile(@PathVariable String id,@PathVariable String projId,HttpServletRequest request){
		int flag=0;
		DFile dFile = dFileService.findById(id);
		BEmployee user =(BEmployee) request.getAttribute("user");
		if (!isOwnerOrAdmin(user, projId) && !dFile.getUploadEmpId().equals(user.getId())) {
			return ResponseResult.fail("你没有该权限", false);
		}
		
		
		 flag = dFileService.deleteById(id);
		
		if(flag==1){
			return ResponseResult.success("文件删除成功", flag);
		}
		
		return ResponseResult.success("文件删除失败", flag);
		
	}
	
	
    public boolean isOwnerOrAdmin(BEmployee bEmployee, String projId) {
		if (bEmployee.getRole().equals("ADMIN")) {
			return true;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("createEmpId", bEmployee.getId());
		map.put("id", projId);
		bProjectService.findByCondition(map);
		return (bProjectService.findByCondition(map) != null);
	}
	
	
	
	
	/**
	 * 服务器上的文件删除是否成功判断
	 * @param filePath
	 * @param fileName
	 * @return
	 */
	public static boolean deleteServerFile(String filePath, String fileName){
		boolean delete_flag = false;
		File file = new File(filePath + fileName);
		if (file.exists() && file.isFile() && file.delete()){
			delete_flag = true;
		}else{
        	delete_flag = false;
		}
		return delete_flag;
	}
	private static String TAG="FileLoad";
	//加密解密 秘钥   和门户之间
	private static final String SEED="d$*16?.ghb#!&bke";
	//分隔符
	public static final String SPLIT_CHAR="|";
	/**
	 * 解码请求应用信息
	 * @param token (appId,cdnToken,responseTimeStamp)
	 * @param decodeType
	 */
	public static Map<String,Object> decodeToken(String token){
		System.out.println(TAG+": decode(token:"+token+") start");
		String userInfoStr=null;
		System.out.println(TAG+": AES decode start");
		userInfoStr=new ThreeDESUtil().getDecString(token, SEED);
		System.out.println(TAG+": AES decode end");
		System.out.println(TAG+": decode() end");
		String userInfos=null;
		Long ms = null;
		if(!StringUtils.isNullOrEmpty(userInfoStr)){
			System.out.println(userInfoStr);
			int i =userInfoStr.indexOf(SPLIT_CHAR);
			userInfos = userInfoStr.substring(0,i);
			ms = Long.parseLong(userInfoStr.substring(i+1));
		}
		Map<String ,Object> map = new HashMap<String,Object>();
		map.put("userInfos", userInfos);
		map.put("ms", ms);
		return map;
	}

	/**
	 * 加密
	 * 
	 * @param appId
	 * @param appKey
	 * @param encodeType
	 * @return
	 */
	public static String generateToken(String userId) {
		long requestTimeStamp = System.currentTimeMillis();
		System.out.println(
				TAG + ": generateToken(userId:" + userId + ",generateTimeStamp:" + requestTimeStamp + ") start");
		String tokenStr = userId + SPLIT_CHAR + requestTimeStamp;
		String token = null;
		System.out.println(TAG + ": AES encode start");
		token = new ThreeDESUtil().getEncString(tokenStr, SEED);
		System.out.println(TAG + ": AES encode end");
		return token;
	}
	
	 
	    private static String[] IEBrowserSignals = {"MSIE", "Trident", "Edge"};  
	  
	    public static boolean isMSBrowser(HttpServletRequest request) {  
	        String userAgent = request.getHeader("User-Agent");  
	        for (String signal : IEBrowserSignals) {  
	            if (userAgent.contains(signal))  
	                return true;  
	        }  
	        return false;  
	    }  
	


}
